package com.kayeah82.application.avatar.qq.utils;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.CharArrayReader;
import java.io.CharArrayWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.Writer;
import java.nio.charset.Charset;

/**
 * @author kayeah82
 */
public final class IOUtils {
	public static final int DEFAULT_BUFFER_SIZE = 4096;

	public static InputStream res(String path) {
		return res(path, IOUtils.class);
	}

	public static InputStream res(String path, Class<?> clazz) {
		return clazz.getResourceAsStream(path);
	}

	public static InputStream res(String path, ClassLoader loader) {
		return loader.getResourceAsStream(path);
	}

	public static String str(Reader reader) throws IOException {
		return str(DEFAULT_BUFFER_SIZE, reader);
	}

	public static String str(int buffer, Reader reader) throws IOException {
		return io(buffer, reader, new StringWriter()).toString();
	}

	public static String str(InputStream input) throws IOException {
		return str(DEFAULT_BUFFER_SIZE, input);
	}

	public static String str(InputStream input, Charset charset) throws IOException {
		return str(DEFAULT_BUFFER_SIZE, input, charset);
	}

	public static String str(int buffer, InputStream input) throws IOException {
		return io(buffer, input, new StringWriter()).toString();
	}

	public static String str(int buffer, InputStream input, Charset charset) throws IOException {
		return str(buffer, new InputStreamReader(input, charset));
	}

	public static <T extends Writer> T io(String string, T writer) throws IOException {
		return io(DEFAULT_BUFFER_SIZE, string, writer);
	}

	public static <T extends Writer> T io(int buffer, String string, T writer) throws IOException {
		return io(buffer, new StringReader(string), writer);
	}

	public static <T extends OutputStream> T io(String string, T output) throws IOException {
		return io(DEFAULT_BUFFER_SIZE, string, output);
	}

	public static <T extends OutputStream> T io(int buffer, String string, T output) throws IOException {
		return io(buffer, string.getBytes(), output);
	}

	public static char[] io(Reader reader) throws IOException {
		return io(DEFAULT_BUFFER_SIZE, reader);
	}

	public static char[] io(int buffer, Reader reader) throws IOException {
		return io(buffer, reader, new CharArrayWriter()).toCharArray();
	}

	public static byte[] io(InputStream input) throws IOException {
		return io(DEFAULT_BUFFER_SIZE, input);
	}

	public static byte[] io(int buffer, InputStream input) throws IOException {
		return io(buffer, input, new ByteArrayOutputStream()).toByteArray();
	}

	public static <T extends Writer> T io(byte[] bytes, T writer) throws IOException {
		return io(DEFAULT_BUFFER_SIZE, bytes, writer);
	}

	public static <T extends Writer> T io(int buffer, byte[] bytes, T writer) throws IOException {
		return io(buffer, new ByteArrayInputStream(bytes), writer);
	}

	public static <T extends OutputStream> T io(char[] chars, T output) throws IOException {
		return io(DEFAULT_BUFFER_SIZE, chars, output);
	}

	public static <T extends OutputStream> T io(int buffer, char[] chars, T output) throws IOException {
		return io(buffer, new CharArrayReader(chars), output);
	}

	public static <T extends Writer> T io(char[] chars, T writer) throws IOException {
		return io(DEFAULT_BUFFER_SIZE, chars, writer);
	}

	public static <T extends Writer> T io(int buffer, char[] chars, T writer) throws IOException {
		return io(buffer, new CharArrayReader(chars), writer);
	}

	public static <T extends OutputStream> T io(byte[] bytes, T output) throws IOException {
		return io(DEFAULT_BUFFER_SIZE, bytes, output);
	}

	public static <T extends OutputStream> T io(int buffer, byte[] bytes, T output) throws IOException {
		return io(buffer, new ByteArrayInputStream(bytes), output);
	}

	public static <T extends OutputStream> T io(Reader reader, T output) throws IOException {
		return io(DEFAULT_BUFFER_SIZE, reader, output);
	}

	public static <T extends OutputStream> T io(int buffer, Reader reader, T output) throws IOException {
		io(buffer, reader, new OutputStreamWriter(output));
		return output;
	}

	public static <T extends Writer> T io(InputStream input, T writer) throws IOException {
		return io(DEFAULT_BUFFER_SIZE, input, writer);
	}

	public static <T extends Writer> T io(int buffer, InputStream input, T writer) throws IOException {
		return io(buffer, new InputStreamReader(input), writer);
	}

	public static <T extends Writer> T io(Reader reader, T writer) throws IOException {
		return io(DEFAULT_BUFFER_SIZE, reader, writer);
	}

	public static <T extends Writer> T io(int buffer, Reader reader, T writer) throws IOException {
		char[] buf = new char[buffer];

		for (int n; (n = reader.read(buf)) > 0;) {
			writer.write(buf, 0, n);
		}

		return writer;
	}

	public static <T extends OutputStream> T io(InputStream input, T output) throws IOException {
		return io(DEFAULT_BUFFER_SIZE, input, output);
	}

	public static <T extends OutputStream> T io(int buffer, InputStream input, T output) throws IOException {
		byte[] buf = new byte[buffer];

		for (int n; (n = input.read(buf)) > 0;) {
			output.write(buf, 0, n);
		}

		return output;
	}

	public static <T extends OutputStream> T io(File file, T output) throws IOException {
		return io(new FileInputStream(file), output);
	}

	public static byte[] io(File file) throws IOException {
		return io(file, new ByteArrayOutputStream()).toByteArray();
	}
}
